﻿package com.thorqq.magictimer.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.text.DecimalFormat;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import android.content.Context;
import android.os.Environment;
import android.util.Log;

public class Util
{
    private static boolean m_debug = true;
    private static String m_logFileName;
    private static File mFileDir;
    private static File mSDCardDir;
    private static File mSDCardRootDir;
    private static String mAbsoluteLogPath;

    public final static String LOG_NAME = "MagicTimer.log";
    public final static String LOG_PATH = "MagicTimer";

    public static int getLineNumber()
    {
        return Thread.currentThread().getStackTrace()[5].getLineNumber();
    }

    public static String getFileName()
    {
        return Thread.currentThread().getStackTrace()[5].getFileName();
    }

    public static String getClassName()
    {
        return Thread.currentThread().getStackTrace()[4].getClassName();
    }

    public static String getMethodName()
    {
        return Thread.currentThread().getStackTrace()[4].getMethodName();
    }

    public static void printCallStatck()
    {
        StackTraceElement[] stackElements = Thread.currentThread()
                .getStackTrace();
        if (stackElements != null)
        {
            StringBuffer buf = new StringBuffer();
            for (int i = 0; i < stackElements.length; i++)
            {
                buf.append(stackElements[i].getClassName()).append("\t")
                        .append(stackElements[i].getFileName()).append(":")
                        .append(stackElements[i].getLineNumber()).append("\n");
            }
            Util.log(buf.toString());
        }
    }

    public static File getSDCardRootDir()
    {
        if (mSDCardRootDir != null)
        {
            return mSDCardRootDir;
        }

        String path = Environment.getExternalStorageDirectory().getPath();
        mSDCardRootDir = new File(path);

        return mSDCardRootDir;
    }

    public static File getSDCardDir()
    {
        if (mSDCardDir != null)
        {
            return mSDCardDir;
        }

        String path = Environment.getExternalStorageDirectory().getPath() + "/"
                + LOG_PATH;
        mSDCardDir = new File(path);
        if (!mSDCardDir.exists() && !mSDCardDir.mkdir())
        {
            return null;
        }

        return mSDCardDir;
    }
    
    public static File getFileDir(Context context)
    {
        if (mFileDir != null)
        {
            return mFileDir;
        }

        String path = context.getFilesDir().getPath();
        mFileDir = new File(path);
        if (!mFileDir.exists() && !mFileDir.mkdir())
        {
            return null;
        }

        return mFileDir;
    }

//    public static void saveData(String filename, String str)
//    {
//        try
//        {
//            FileOutputStream fout = new FileOutputStream(getBaseDir().getPath()
//                    + "/" + filename);
//            byte[] bytes = str.getBytes();
//            fout.write(bytes);
//            fout.close();
//        }
//        catch (Exception e)
//        {
//            Util.log(e.getMessage());
//        }
//    }

    public static void initLog(Context context)
    {
        initLog(context, null);
    }
    
    public static void initLog(Context context, String filename)
    {
        try
        {
            m_logFileName = (filename == null ? LOG_NAME : filename);
            File sdcardDir = getSDCardDir();
            if(sdcardDir == null)
            {
                Log.e(getFileName()+ ":" + getLineNumber(), "mAbsoluteLogPath is null");
                mAbsoluteLogPath = null;
                return;
            }
            File file = new File(getSDCardDir().getAbsolutePath() + "/" + m_logFileName);
            if (file.exists())
            {
                file.delete();
            }
            mAbsoluteLogPath = file.getAbsolutePath();
            log("Log initital success.");
        }
        catch (Exception e)
        {
            e.printStackTrace();
            mAbsoluteLogPath = null;
        }

    }

    public static boolean is_debug()
    {
        return m_debug;
    }
    
    public static void setDebug(boolean b)
    {
        m_debug = b;
    }

    public static void log_ex(Exception e)
    {
        e.printStackTrace();
        if (mAbsoluteLogPath == null)
        {
            return;
        }

        StringWriter sw = new StringWriter();
        e.printStackTrace(new PrintWriter(sw));
        Util.logByForce(sw.getBuffer().toString());
    }
    
    public static void logByForce(String str)
    {
        Util.log(str, true);
    }

    public static void log(String str)
    {
        Util.log(str, false);
    }
    
    private static void log(String str, boolean force)
    {
        if (m_debug == false && force == false)
        {
            return;
        }

        try
        {
//            if(str.length() > 1024)
//            {
//                str = str.substring(0, 1000) + ". Real length is " + str.length();
//            }
            
            byte[] bytes = ("[" + DateUtil.getDate() + "][" + getFileName() + ":"
                    + getLineNumber() + "]>> " + str + "\n").getBytes();

            Log.d(getFileName()+ ":" + getLineNumber(), str);
            
            if(mAbsoluteLogPath != null)
            {
                boolean append = true;
                FileOutputStream fout = new FileOutputStream(mAbsoluteLogPath, append);
                fout.write(bytes);
                fout.close();
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }
    
    public static void log(Class<?> c)
    {
        StringBuffer tmp = new StringBuffer();
        Constructor<?>[] theConstructors = c.getDeclaredConstructors(); 
        for (int i = 0; i < theConstructors.length; i++) 
        {
            int mod = theConstructors[i].getModifiers();    // 输出修饰域和方法名称
            tmp.append(java.lang.reflect.Modifier.toString(mod)).append(" ").append(c.getName()).append("(");

            Class<?>[] parameterTypes = theConstructors[i].getParameterTypes();       // 获取指定构造方法的参数的集合
            for (int j = 0; j < parameterTypes.length; j++) 
            {    // 输出打印参数列表
                tmp.append(parameterTypes[j].getName());
                if (parameterTypes.length > j+1) 
                {
                    tmp.append(", ");
                }
            }
            tmp.append(")");
            Util.log(tmp.toString());
        }
    }

    // 整形与字符串互转
    public static int strToInt(String s)
    {
        return s.equals("") ? 0 : Integer.parseInt(s);
    }

    public static String intToStr(int i)
    {
        return new String(i + "");
    }

    public static String intToStr(long i)
    {
        return new String(i + "");
    }

    // 统一半角全角括号
    public static String Bracket(String src)
    {
        return src.replace('(', '（').replace(')', '）');
    }

    public static void unZip(String zipFile, String targetDir)
    {
        int BUFFER = 4096; // 这里缓冲区我们使用4KB，
        String strEntry; // 保存每个zip的条目名称

        try
        {
            BufferedOutputStream dest = null; // 缓冲输出流
            FileInputStream fis = new FileInputStream(zipFile);
            ZipInputStream zis = new ZipInputStream(
                    new BufferedInputStream(fis));
            ZipEntry entry; // 每个zip条目的实例

            while ((entry = zis.getNextEntry()) != null)
            {

                try
                {
                    int count;
                    byte data[] = new byte[BUFFER];
                    strEntry = entry.getName();

                    File entryFile = new File(targetDir + strEntry);
                    File entryDir = new File(entryFile.getParent());
                    if (!entryDir.exists())
                    {
                        entryDir.mkdirs();
                    }

                    FileOutputStream fos = new FileOutputStream(entryFile);
                    dest = new BufferedOutputStream(fos, BUFFER);
                    while ((count = zis.read(data, 0, BUFFER)) != -1)
                    {
                        dest.write(data, 0, count);
                    }
                    dest.flush();
                    dest.close();
                }
                catch (Exception e)
                {
                    log_ex(e);
                }
            }
            zis.close();
        }
        catch (Exception e)
        {
            log_ex(e);
        }
    }

    public static final String PARAMES_SEPARATOR = "\\|"; // 分隔符
    public static final String PARAMES_HYPHEN = "|"; // 连字符

    public static String[] splitParames(String param_in)
    {
        return splitParames(param_in, PARAMES_SEPARATOR);
    }

    public static String[] splitParames(String param_in, String separator)
    {
        return param_in.split(separator);
    }

    public static String arrayToString(char[] array)
    {
        return array == null ? new String("-1") : new String(array);
    }

    public static void initializeCharArray(char[] a, char defaultValue)
    {
        for (int i = 0; i < a.length; i++)
        {
            a[i] = defaultValue;
        }
    }

    public static String sizeFormat(long size)
    {
        DecimalFormat df = new DecimalFormat("#0.00");
        String total=(size*1.0/1024)<1024?df.format(size*1.0/1024)+"KB"
                :(size*1.0/1024/1024)<1024?df.format(size*1.0/1024/1024)+"MB"
                        :df.format(size*1.0/1024/1024/1024)+"GB";
        return total;
        
    }

}
